package utils

import (
	"fmt"
	"net/url"
	"reflect"
	"strconv"
	"strings"
	"time"

	"github.com/go-resty/resty/v2"
)

var defaultRestyClient = resty.New().SetTimeout(10 * time.Second)

type PostOption struct {
	Url     string
	Params  url.Values
	Headers map[string]string
}

func Post(opt *PostOption) (*resty.Response, error) {
	resp, err := defaultRestyClient.R().
		SetHeaders(opt.Headers).
		SetBody(opt.Params.Encode()).
		SetHeader("Content-Type", "application/x-www-form-urlencoded").
		Post(opt.Url)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func StructToValues(v any) url.Values {
	values := make(url.Values)
	typ := reflect.TypeOf(v).Elem()
	val := reflect.ValueOf(v).Elem()
	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		value := val.Field(i)
		tag := field.Tag.Get("structure2value") // 获取 tag
		if tag == "" {
			continue // 跳过无 tag 字段
		}
		key := strings.Split(tag, ",")[0] // 处理 tag 中的 ,omitempty 等修饰符
		if key == "" {
			continue
		}
		switch value.Kind() {
		case reflect.String:
			strVal := value.String()
			if strVal != "" {
				values.Set(key, strVal)
			}
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			values.Set(key, strconv.FormatInt(value.Int(), 10))
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			values.Set(key, strconv.FormatUint(value.Uint(), 10))
		case reflect.Bool:
			values.Set(key, strconv.FormatBool(value.Bool()))
		case reflect.Float32, reflect.Float64:
			values.Set(key, fmt.Sprintf("%f", value.Interface()))
		case reflect.Slice:
			if reflect.TypeOf(value.Interface()).Elem().Kind() == reflect.String {
				slice := value.Slice(0, value.Len())
				str := make([]string, slice.Len())
				for i := 0; i < slice.Len(); i++ {
					str[i] = slice.Index(i).String()
				}
				values[key] = str
			}
		default:
			// 其他类型可扩展
		}
	}
	return values
}
